import XLSX from 'xlsx'
import {formatterTime} from './resources'
var tmpDown; //导出的二进制对象
function downloadExl(downloadName, json, type) {
    var tmpdata = json[0];
    json.unshift({});
    var keyMap = []; //获取keys
    for (var k in tmpdata) {
        keyMap.push(k);
        json[0][k] = k;
    }
    var tmpdata = []; //用来保存转换好的json 
    json.map((v, i) => keyMap.map((k, j) => Object.assign({}, {
        v: v[k],
        position: (j > 25 ? getCharCol(j) : String.fromCharCode(65 + j)) + (i + 1)
    }))).reduce((prev, next) => prev.concat(next)).forEach((v, i) => tmpdata[v.position] = {
        v: v.v
    });
    var outputPos = Object.keys(tmpdata); //设置区域,比如表格从A1到D10
    var tmpWB = {
        SheetNames: ["sheet"], //保存的表标题
        Sheets: {
            "sheet": Object.assign({},
                tmpdata, //内容
                {
                    '!ref': outputPos[0] + ':' + outputPos[outputPos.length - 1] //设置填充区域
                })
        }
    };
    tmpDown = new Blob([s2ab(XLSX.write(tmpWB, {
            bookType: (type == undefined ? 'xlsx' : type),
            bookSST: false,
            type: 'binary'
        } //这里的数据是用来定义导出的格式类型
    ))], {
        type: ""
    }); //创建二进制对象写入转换好的字节流
    var href = URL.createObjectURL(tmpDown); //创建对象超链接
    document.getElementById("hf").download = downloadName;
    document.getElementById("hf").href = href; //绑定a标签
    document.getElementById("hf").click(); //模拟点击实现下载
    setTimeout(function() { //延时释放
        URL.revokeObjectURL(tmpDown); //用URL.revokeObjectURL()来释放这个object URL
    }, 100);
}

function s2ab(s) { //字符串转字符流
    var buf = new ArrayBuffer(s.length);
    var view = new Uint8Array(buf);
    for (var i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
    return buf;
}
// 将指定的自然数转换为26进制表示。映射关系：[0-25] -> [A-Z]。
function getCharCol(n) {
    let temCol = '',
        s = '',
        m = 0
    while (n > 0) {
        m = n % 26 + 1
        s = String.fromCharCode(m + 64) + s
        n = (n - m) / 26
    }
    return s
}

/**
 * 格式化数据 
 * 
 * @param {any} datas 原数据
 * @param {any} hideFields 不要的属性
 * @param {any} formatterField 格式化属性名 {'原属性名':'表中显示属性名'}
 * @param {any} formatterFunction 格式化数据方法{'属性名':function(数据) {return 显示数据}}
 * @returns 
 */
function formatterData(datas, hideFields, formatterField, formatterFunction) {
    var newDatas = [];
    datas.forEach(data => {
        newDatas.push(getSingleData(data, hideFields, formatterField, formatterFunction));
    })
    return newDatas;
}

function getSingleData(data, hideFields, formatterField, formatterFunction) {
    var obj = {};
    for (var key in data) {
        if (showField(key, hideFields)) {
            obj[formatterFieldName(key, formatterField)] = formatterFieldData(data[key], key, formatterFunction);
        }
    }

    return obj;
}

function showField(key, hideFields) {
    if (PULICE_HIDE_FIELDS.indexOf(key) >= 0) {
        return false;
    }
    if (hideFields && hideFields.indexOf(key) >= 0) {
        return false;
    }

    return true
}
/**
 * 删除不要的属性
 * 
 * @param {any} data 
 * @param {any} hideFields 
 */
function hideFieldData(data, hideFields) {
    PULICE_HIDE_FIELDS.forEach(hideField => {
        delete data[hideField];
    })
    if (hideFields) {
        hideFields.forEach(hideField => {
            delete data[hideField];
        })
    }
}
const PULICE_HIDE_FIELDS = ['id', 'uid', 'eid', 'eyes', 'updatedAt', 'createdAt', 'age'];
const PULICE_FIFLDS_NAME = {
    'etype': '试卷类型',
    'answer': '答案数据',
    'images': '左右眼照片地址',
    'status': '状态',
    'time': '创建时间',
    'ctime': '创建时间',
    'stime': '开始用药时间',
    'utime': '记录时间',
    'etime': '结束时间',
    'phone': '手机号码',
    'address': '地址',
    'sex': '性别',
    'age': '年龄',
    'name': '姓名',
    'nickname': '昵称',
    'nickName': '昵称',
    'integral': '积分',
    'ranking': '进入顺序',
    'remark': '备注',
    'stem': '题干',
    'joinTime':'加入时间'
};
const PULICE_FORMATTERFUNCTION = {
    etype: function(etype) {
        return formatterEtype(etype);
    },
    ctime: function(ctime) {
        return formatterDetailTime(ctime);
    },
    time: function(time) {
        return formatterDetailTime(time);
    },
    stime: function(time) {
        return formatterDetailTime(time);
    },
    utime: function(time) {
        return formatterDetailTime(time);
    },
    etime: function(time) {
        return formatterDetailTime(time);
    },joinTime:function(time) {
        return formatterDetailTime(time);
    },
    sex: function(sex) {
        return { 1: '男', 2: '女' }[sex];
    },
};

function formatterEtype(etype) {
    return {
        1: '用药6小时内问卷',
        2: '用药6小时后问卷',
        3: '用药2天问卷',
        4: '用药3天问卷',
        5: '用药5天问卷',
        6: '用药7天问卷',
        7: '用药14天问卷',
        8: '用药一个月问卷',
        98: '首次答卷',
        99: '既往病史',
        100: '用药反馈',
    }[etype];
}

function formatterDetailTime(time) {
    if (time == 0) {
        return '未设置';
    }
    var date = new Date(time * 1000);
    var year = date.getFullYear()
    var month = date.getMonth() + 1
    var day = date.getDate()

    var hour = date.getHours()
    var minute = date.getMinutes()
    var second = date.getSeconds();

    var format = function(val) {
        if (val < 10) {
            return "0" + val;
        } else {
            return val;
        }
    }
    return year + "-" + format(month) + "-" + format(day) + " " + format(hour) + ":" + format(minute) + ":" + format(second);
}
/**
 * 默认的格式化属性名
 * 
 * @param {any} key 
 * @returns 
 */
function defaultFormatterFieldName(key) {
    var fieldName = PULICE_FIFLDS_NAME[key];
    if (fieldName) {
        return fieldName;
    }
    return key;
}
/**
 * 格式化属性名
 * 
 * @param {any} key 
 * @param {any} formatterField 
 * @returns 
 */
function formatterFieldName(key, formatterField) {
    if (formatterField) {
        var fieldName = formatterField[key];
        if (fieldName) {
            return fieldName;
        }
    }
    return defaultFormatterFieldName(key);
}
/**
 * 格式化属性名对应的数据
 * 
 * @param {any} data 
 * @param {any} key 
 * @param {any} formatterFunction 
 * @returns 
 */
function formatterFieldData(data, key, formatterFunction) {
    if (formatterFunction) {
        var formatterFunc = formatterFunction[key];
        if (formatterFunc) {
            return formatterFunc(data);
        }
    }
    return defaultFormatterFunc(data, key);
}
/**
 * 默认的格式化数据的方法
 * 
 * @param {any} data 
 * @param {any} key 
 * @returns 
 */
function defaultFormatterFunc(data, key) {
    var formatterFunc = PULICE_FORMATTERFUNCTION[key];
    if (formatterFunc) {
        return formatterFunc(data);
    }
    return data;
}

function getAnswerMap(answers) {
    const map = new Map()
    answers.forEach(answer => {
        map.set(answer.etype,answer.answer)
    })
    return map
}

function formatterExcelData(users) {
    const tableHead = [
        ['姓名','昵称','性别','手机号','积分','地址','首诊时间','医生姓名','医生手机','所在医院','城市','省份','代表大区','代表省','代表市','代表医院','代表姓名','代表手机'],
        ["问卷完成总进度"],
        ['6小时内问卷完成度','1-1','1-2','1-3','1-4','1-5','1-6','1-7','1-8','1-9','1-10'],//1
        ['6小时后问卷完成度','2-1','2-2','2-3','2-4','2-5','2-6','2-7','2-8','2-9','2-10'],//2
        ['第二天问卷完成度','3-1','3-2','3-3','3-4','3-5','3-6','3-7','3-8','3-9','3-10','3-11','3-12','3-13'],//3
        ['第三天问卷完成度','4-1','4-2','4-3','4-4','4-5','4-6','4-7','4-8','4-9','4-10','4-11','4-12','4-13'],//4
        ['第五天问卷完成度','5-1','5-2','5-3','5-4','5-5','5-6','5-7','5-8','5-9','5-10','5-11','5-12','5-13'],//5
        ['第七天问卷完成度','6-1','6-2','6-3','6-4','6-5','6-6','6-7','6-8','6-9','6-10','6-11','6-12','6-13'],//6
        ['第十四天问卷完成度','7-1','7-2','7-3','7-4','7-5','7-6','7-7','7-8','7-9','7-10','7-11','7-12','7-13'],//7
        ['一个月问卷完成度','8-1','8-2','8-3','8-4','8-5','8-6','8-7','8-8','8-9','8-10','8-11','8-12','8-13'],//8
        ['一个月问卷完成度','9-1','9-2','9-3','9-4','9-5','9-6','9-7'],//98
        ['既往病史问卷完成度','10-1','10-2','10-3','10-4','10-5','10-6','10-7','10-8','10-9','10-10','10-11','10-12','10-13','10-14','10-15','10-16','10-17','10-18','10-19'],//99
        ['用药反馈问卷完成度','11-1','11-2','11-3','11-4','11-5'],//100
    ]
    const data = []
    const types = [
        {etype:1,index:2},
        {etype:2,index:3},
        {etype:3,index:4},
        {etype:4,index:5},
        {etype:5,index:6},
        {etype:6,index:7},
        {etype:7,index:8},
        {etype:8,index:9},
        {etype:98,index:10},
        {etype:99,index:11},
        {etype:100,index:12},
    ]
    let space = {}
    tableHead.forEach(items => {
        items.forEach(item => {
            space[item] = ''
        })
    })
    data.push(space)
    console.log("users",users)
    users.forEach(user => {
        let obj = {}
        let answerMap = getAnswerMap(user.answers)
        obj[tableHead[0][0]]  = user.name || ''
        obj[tableHead[0][1]]  = user.nickName || ''
        obj[tableHead[0][2]]  = (user.sex == 1 ? '男' : '女') || ''
        obj[tableHead[0][3]]  = user.phone || ''
        obj[tableHead[0][4]]  = user.integral || ''
        obj[tableHead[0][5]]  = user.address || ''
        obj[tableHead[0][6]]  = user.ftime ?  formatterTime(user.ftime)  : ''
        obj[tableHead[0][7]]  = (user.doctor && user.doctor.name) || ''
        obj[tableHead[0][8]]  = (user.doctor && user.doctor.phone) || ''
        obj[tableHead[0][9]]  = (user.doctor && user.doctor.hospital) || ''
        obj[tableHead[0][10]] = user.city || ''
        obj[tableHead[0][11]] = user.province || '' 
        obj[tableHead[0][12]] = user.mr_region || '' 
        obj[tableHead[0][13]] = user.mr_province || '' 
        obj[tableHead[0][14]] = user.mr_city || '' 
        obj[tableHead[0][15]] = user.mr_hospital || '' 
        obj[tableHead[0][16]] = user.mr_name || '' 
        obj[tableHead[0][17]] = user.mr_phone || '' 
        let totleProgress    = 0
        types.forEach(type => {
             let answer = answerMap.get(type.etype)
             if(answer) {
                 answer = JSON.parse(answer)
                 let totle    = answer.length
                 let complete = 0
                 for(let i = 0 ; i < answer.length ; i++) {
                     obj[tableHead[type.index][i + 1]] = `问：${answer[i].stem}  答：${answer[i].value}`
                    if(answer[i].value) {
                        complete++;
                    }
                 }
                 let progress = Math.round( complete / totle * 100) 
                 totleProgress += progress
                 obj[tableHead[type.index][0]] = progress + "%"
             } else {
                 obj[tableHead[type.index][0]] = "0%"
             }
        })
        totleProgress = Math.round( totleProgress / 11 ) 
        totleProgress += "%"
        obj[tableHead[1][0]] = totleProgress
        data.push(obj)


    })
    return data
}
module.exports = {
    downloadExl: downloadExl,
    formatterData: formatterData,
    formatterEtype: formatterEtype,
    formatterExcelData:formatterExcelData
};